﻿using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Globalization;
using System.Windows.Threading;


namespace BeerManagementSystem
{
    /// <summary>
    /// Interaktionslogik für CheckIn.xaml
    /// </summary>
    public partial class CheckIn
    {
        private Inviter _inv;
        private AssignCard _assignCard;
        public ObservableCollection<BeerboxItem> BeerboxItems { get; set; }
        public ObservableCollection<Image> MessageImages { get; set; }
        private int _beerboxItemCounter ;
        private static CheckIn _instance;

        public static CheckIn Instance
        {
            get { return _instance ?? (_instance = new CheckIn()); }
        }

        private CheckIn()
        {
            BeerboxItems = new ObservableCollection<BeerboxItem>();
            MessageImages = new ObservableCollection<Image>();
            _beerboxItemCounter = 0;
            
            try
            {
                InitializeComponent();
                
            }
            catch (Exception e)
            {
                Console.WriteLine(e.StackTrace);
                
            }

        }



        public bool BeerboxIsOpen { get; set; }

        public bool BeerboxWriteMode { get; set; }

        /**
         * Wird aufgerufen wenn das fenster geladen wird
         * */

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {

            SetStatusContentLabel("Bitte ziehen Sie durch. Dann zapfen.");
            statusLabel.Content = "Beermode";
            isOnlineLabel.Foreground = Properties.Settings.Default.WebConnectorStatus
                                           ? Brushes.GreenYellow
                                           : Brushes.Red;
            isOnlineLabel.Content = "Online Status: " + Properties.Settings.Default.WebConnectorStatus;
        }



        public void ShowGood(string message)
{            CardReaderStatusLabel.Background = Brushes.Transparent;
            CardReaderStatusLabel.Content = message;
            CardReaderStatusLabel.Foreground = Brushes.Black;
            CardReaderStatusLabel.Margin = new Thickness(400, 0, 400, 950);

        }

        public void ShowNeutral(string message)
        {
            var ownYellowBrush = new SolidColorBrush {Color = Color.FromArgb(255, 208, 168, 64)};

            // Describes the brush's color using RGB values. 
            // Each value has a range of 0-255.
            CardReaderStatusLabel.Background = ownYellowBrush;
            CardReaderStatusLabel.Content = message;
            CardReaderStatusLabel.Margin = new Thickness(0);

        }

        public void ShowBad(string message)
        {
            var ownRedBrush = new SolidColorBrush {Color = Color.FromArgb(255, 94, 24, 27)};

            // Describes the brush's color using RGB values. 
            // Each value has a range of 0-255.
            CardReaderStatusLabel.Background = ownRedBrush;
            CardReaderStatusLabel.Content = message;
            CardReaderStatusLabel.Margin = new Thickness(0);

        }

        public void ShowTransp(string message)
        {
            var ownTransparentBrush = new SolidColorBrush {Color = Color.FromArgb(0, 94, 24, 27)};

            // Describes the brush's color using RGB values. 
            // Each value has a range of 0-255.
            CardReaderStatusLabel.Background = ownTransparentBrush;
            CardReaderStatusLabel.Content = message;
            CardReaderStatusLabel.Foreground = Brushes.WhiteSmoke;
        }

        public void ShowAssignCard(string[] names)
        {
            _assignCard = new AssignCard(names);
            AddTabItem(_assignCard, "AssignCard");
            SetStatusLabel("Assigning Card:");
            SetStatusContentLabel("Welchem User wird eine Karte zugewiesen? Warte auf Tastatureingabe. Mit ENTER bestätigen");
            LogWriter.Write("Assigning Mode active", LogWriter.LogLevel.Status, this);
            
        }

        public void InitializeInviter()
        {
            _inv = new Inviter();
            AddTabItem(_inv, "Inviter");
            LogWriter.Write("InviterMode active", LogWriter.LogLevel.Status, this);
            _inv.clearMainCanvasInviter();
            SetStatusLabel("Invitermode:");
            SetStatusContentLabel("Gönner/in, ziehen Sie bitte durch.");
        }

        public void FinalizeInviter()
        {
            statusLabel.Content = "Beermode";
            statusContentLabel.Content = "Bitte ziehen Sie durch.";
            mainTabControl.SelectedItem = mainTabControl.Items[0];
            LogWriter.Write("InviterMode inactive", LogWriter.LogLevel.Status, this);
        }

        /// <summary>
        /// Methoden um Tabitems im Tabcontrol hinzuzufügen oder zu löschen
        /// </summary>
        /// <param name="o"></param>
        /// <param name="header"></param>
        private void AddTabItem(object o, string header)
        {
            var item = new TabItem
                {
                    Header = header,
                    Content = o,
                    TabIndex = mainTabControl.Items.Count,
                };
            mainTabControl.Items.Add(item);
            mainTabControl.SelectedItem = mainTabControl.Items[item.TabIndex];
        }

        public void InitializeGameCd(UserProfile playerUserProfile, int rndTime)
        {
            var gameCdTab = GameCdTab.Instance;
            gameCdTab.SetRoundTime = rndTime;
            gameCdTab.PlayerImage.Source = playerUserProfile.BitmapImage;
            gameCdTab.playerNameLabel.Content = playerUserProfile.User.FirstName + " " + playerUserProfile.User.LastName;
            if (playerUserProfile.User.Duration_total == 0) gameCdTab.playerBphLabel.Content = "-";
            else gameCdTab.playerBphLabel.Content = Math.Round((decimal)(playerUserProfile.User.Beer_total / playerUserProfile.User.Duration_total), 3);
            if (playerUserProfile.User.Account_game != null)
                gameCdTab.gamePointTextbox.Text = Math.Round((decimal)playerUserProfile.User.Account_game,0).ToString(CultureInfo.InvariantCulture);
            AddTabItem(gameCdTab, "GameCd");
            gameCdTab.StartGame();
        }

        internal void FinalizeGameCd()
        {
            DeleteSelectedTabItem(GetTabItem("GameCd"));
            mainTabControl.SelectedItem = mainTabControl.Items[0];
            statusLabel.Content = "Beermode";
            statusContentLabel.Content = "Bitte ziehen Sie durch.";
        }

        public void DeleteSelectedTabItem()
        {
            mainTabControl.Items.Remove(mainTabControl.SelectedItem);
        }

        public void DeleteSelectedTabItem(object o)
        {
            mainTabControl.Items.Remove(o);

        }

        public void SetStatusLabel(string str)
        {
            statusLabel.Content = str;
        }

        public void SetStatusContentLabel(string str)
        {
            statusContentLabel.Content = str;
        }

        internal void SetInviterImage(BitmapImage bitmapImage)
        {
            _inv.imageInviter.Source = bitmapImage;
        }

        internal void AddInvitedUserImage(BitmapImage bitmapImage)
        {
            _inv.addPicture(bitmapImage);
        }

        internal void SetForegroundColor(SolidColorBrush color, Control control)
        {
            control.Foreground = color;
        }

        internal void SetForegroundColor(SolidColorBrush color, System.Windows.Shapes.Shape shape)
        {
            shape.Stroke = color;
        }

        internal void UpdateLiquidity(bool p)
        {
            SetForegroundColor(p ? Brushes.White : Brushes.Red, beerbillEllipse);
        }

        internal void UpdateRanking(Ranking ranking)
        {
            //ranking listen leeren

            topTenListBox.Items.Clear();
            topTenValueListBox.Items.Clear();

            monthlyTopTenListBox.Items.Clear();
            monthlyTopTenValueListBox.Items.Clear();

            dailyTopTenListBox.Items.Clear();
            dailyTopTenValueListBox.Items.Clear();


            for (int i = 0; i < ranking.GetRankingTotal().Count(); i++)
            {
                topTenListBox.Items.Add(String.Format("{0}.\t{1} {2}", i + 1, ranking.GetRankingTotal()[i].FirstName,
                                                      ranking.GetRankingTotal()[i].LastName));
                topTenValueListBox.Items.Add(String.Format("{0}", ranking.GetRankingTotal()[i].Beer_total));
            }

            for (int i = 0; i < ranking.GetRankingMonth().Count(); i++)
            {
                monthlyTopTenListBox.Items.Add(String.Format("{0}.\t{1} {2}", i + 1,
                                                             ranking.GetRankingMonth()[i].FirstName,
                                                             ranking.GetRankingMonth()[i].LastName));
                monthlyTopTenValueListBox.Items.Add(String.Format("{0}", ranking.GetRankingMonth()[i].Beer_month));
            }

            for (int i = 0; i < ranking.GetRankingDay().Count(); i++)
            {

                dailyTopTenListBox.Items.Add(String.Format("{0}.\t{1} {2}", i + 1, ranking.GetRankingDay()[i].FirstName,
                                                           ranking.GetRankingDay()[i].LastName));
                dailyTopTenValueListBox.Items.Add(String.Format("{0}", ranking.GetRankingDay()[i].Beer_day));
            }

            // Initialisiert die Monats TopTen Liste

            monthlyTopTenLabel.Content = String.Format("{0} {1}", "",
                                                       CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(
                                                           ranking.GetDayStart().Month) + " " + DateTime.Now.Year);
            monthlyCountLabel.Content = Ranking.GetMonthBeerCount();


            // Initialisiert die Tages TopTen Liste
            dailyTopTenLabel.Content = ranking.GetDayStart().DayOfWeek == DayOfWeek.Wednesday
                                           ? String.Format("{0} {1}", "",
                                                           "Schmidtwoch, den " +
                                                           ranking.GetDayStart().ToShortDateString())
                                           : String.Format("{0} {1}", "",
                                                           CultureInfo.CurrentCulture.DateTimeFormat.GetDayName(
                                                               ranking.GetDayStart().DayOfWeek) + ", den " +
                                                           ranking.GetDayStart().ToShortDateString());
            dailyCountLabel.Content = Ranking.GetDayBeerCount();

            BeerTotalLabel.Content = Ranking.GetTotalBeerCount();

        }

        public void SetBarrelStatus(int count)
        {
            BarrelFullnessLabel.Content = count;

            if (count <= barrelFullnessProgressBar.Maximum)
            {
                if (count < 50) barrelFullnessProgressBar.Foreground = Brushes.LimeGreen;
                else if (count < 60) barrelFullnessProgressBar.Foreground = Brushes.Yellow;
                else barrelFullnessProgressBar.Foreground = Brushes.Red;
                barrelFullnessProgressBar.Value = barrelFullnessProgressBar.Maximum - count;
            }


            else barrelFullnessProgressBar.Value = barrelFullnessProgressBar.Minimum;
        }

        public void UpdateUserProfile(UserProfile userProfile, Transaction lasTransaction)
        {
            userImage.Source = userProfile.BitmapImage;
            lastTransactionNameLabel.Content = userProfile.User.LastName;
            lastTransactionVornameLabel.Content = userProfile.User.FirstName;
            lastTransactionCountLabel.Content = String.Format("{0}", userProfile.User.Beer_total);
            lastTransactionTimeLabel.Content = String.Format("Letzte Transaktion: {0} um {1} Uhr",
                                                             lasTransaction.Timestamp.ToShortDateString(),
                                                             lasTransaction.Timestamp.ToLongTimeString());
            userTitleLabel.Content = userProfile.User.Title;
            userHobbiesTextBox.Text = userProfile.User.Hobbies;
            userInfoTextbox.Text = userProfile.User.UserInfo;
            userAccountBeerbillValue.Content = String.Format("{0} €", userProfile.User.Account_beerbill);
            userAccountGameValue.Content = userProfile.User.Account_game; 
            if (lasTransaction.User.Duration_total != null)
            {
                int days = (int) lasTransaction.User.Duration_total/24;
                decimal hours = (decimal) lasTransaction.User.Duration_total% 24;
                durationDayValueLabel.Content =  days.ToString(CultureInfo.InvariantCulture);
                durationHourValueLabel.Content = Math.Round(hours, 2).ToString(CultureInfo.InvariantCulture);
                
                if (lasTransaction.User.Duration_total == 0) userBphLabel.Content = "-";
                else userBphLabel.Content = Math.Round((decimal) (lasTransaction.User.Beer_total/lasTransaction.User.Duration_total), 3);
            }
            lastTransactionPositionLabel.Content = String.Format("{0}", userProfile.CurrentRank);

            rangNameLabel.Content = userProfile.CurrentDegree;
            rangName2Label.Content = userProfile.NextDegree;
            rangProgressBar.Minimum = userProfile.CurrentDegreeValue;
            rangProgressBar.Maximum = userProfile.NextDegreeValue;
            rangProgressBar.Value = Convert.ToInt32(userProfile.User.Beer_total);

        }

        public void ToggleTab(string direction)
        {
            if (direction.ToLower().Equals("left") && mainTabControl.SelectedIndex > 0)
            {
                mainTabControl.SelectedItem = mainTabControl.SelectedIndex - 1;
            }
            else
            {
                if (mainTabControl.SelectedIndex < mainTabControl.Items.Count)
                {
                    mainTabControl.SelectedItem = mainTabControl.SelectedIndex + 1;
                }
            }
        }

        private void Window_KeyDown(object sender, KeyEventArgs e)
        {

        }

        public void ShowGood()
        {
            ShowGood("");
        }

        public void ShowTransp()
        {
            ShowTransp("Bereit...");
        }

        public void CreateLogForm(StreamReader streamReader)
        {
            var logForm = new LogForm(streamReader);
            AddTabItem(logForm, "Log");
            

        }

        public void UpdateBeerDocterProfile(BeerdocterProfile bd)
        {
            beerDocterFirstNameLabel.Content = bd.Beerdocter.User.FirstName;
            beerDocterLastNameLabel.Content = bd.Beerdocter.User.LastName;
            beerDocterTitleLabel.Content = bd.Beerdocter.Title;
            beerDocterRangLabel.Content = bd.Beerdocter.Rang;
            if (bd.Beerdocter.Date != null)
                beerDocterDateLabel.Content =
                    CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(bd.Beerdocter.Date.Value.Month) + " " +
                    bd.Beerdocter.Date.Value.Year;
            beerdocterBeerLabel.Content = bd.Beerdocter.Beer;
            beerDocterImage.Source = bd.BitmapImage;
        }

        public bool AssignMode()
        {
            return _assignCard != null;
        }

        public string GetAssigningName()
        {

            return _assignCard.userNameComboBox.Text;
        }

        public void StartAssigning()
        {
            SetStatusContentLabel("Zieh die Karte für den User durch...");
        }

        public void AssigningOverwrite(string name)
        {
            SetStatusContentLabel("Die Karte ist momentan: " + name + " zugewiesen. Überschreiben? n/y");
        }

        public void FinalizeAssignCard()
        {
            DeleteSelectedTabItem();
            SetStatusLabel("Beermode:");
            SetStatusContentLabel("Bitte ziehen Sie durch.");
            LogWriter.Write("Assigning Mode inactive", LogWriter.LogLevel.Status, this);
            _assignCard = null;
        }

        public void SuggestCreateUser()
        {
            SetStatusContentLabel("User nicht vorhanden. Anlegen? (y/n)");
        }

        public void DeactivateCombobox()
        {
            _assignCard.userNameComboBox.IsEditable = false;
        }

        public object GetTabItem(string header)
        {
            var matchingItem =
                mainTabControl.Items.Cast<TabItem>().FirstOrDefault(item => (string) item.Header == header);
            return matchingItem;
        }

        public void OpenBeerbox()
        {
            beerBoxGrid.Height = 680;
            beerboxLabel.Content = "BEERBOX";
            BeerboxIsOpen = true;
        }

        public void CloseBeerbox()
        {
            beerBoxGrid.Height = 100;
            beerboxLabel.Content = "BB";
        }

        public void ToggleBeerbox()
        {
            if (beerBoxGrid.Height > 150)
            {
                beerBoxGrid.Height = 100;
                BeerboxIsOpen = false;
            }
            else
            {
                beerBoxGrid.Height = 680;
                BeerboxIsOpen = true;
            }
        }

        public void AddItemToBeerbox(BeerboxItem bbi)
        {
            
            if (bbi == null) _beerboxItemCounter++;
            else
            {
                double height = 100;
                Dispatcher.Invoke(DispatcherPriority.Send, (ThreadStart)delegate { height = beerBoxGrid.Height; });
                if (200 > height) 
                    Dispatcher.Invoke(DispatcherPriority.Normal, new Action(OpenBeerbox));
                Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => BeerboxItems.Insert(0, bbi)));
            Console.WriteLine(BeerboxItems.Count);
            }
            if (_beerboxItemCounter > 3)
            {
                _beerboxItemCounter = 0;
                Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(CloseBeerbox));
            }
        }

        public void BeerBoxWrite()
        {
            BeerBoxInputTextBox.Focus();
            BeerBoxInputTextBox.Text = "";
        }

        public void BeerBoxGetFocus()
        {
            beerBox.Focus();
        }

        public DateTime GetTimestampFromListBoxItem(BeerboxItem lItem)
        {
            return BeerboxItems.Where(i => i == lItem).Select(i => i.Timestamp).First(); 
        }

        public void BeerboxReleaseFocus()
        {
            beerBox.SelectedItem = null;
            BeerBoxInputTextBox.Focus();
        }


       
    }
}
